package csl.blog.server.utils;

import cn.hutool.json.JSONUtil;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.AbstractMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * 消息处理
 */
public class JsonMessageConverter extends AbstractMessageConverter {

    private static final String DEFAULT_CHARSET = "UTF-8";

    private static final Map<String, Function<Message, Object>> MSG_CONVERT_MAP = new HashMap<>();

    static {
        MSG_CONVERT_MAP.put(MessageProperties.CONTENT_TYPE_BYTES, Message::getBody);
        MSG_CONVERT_MAP.put(MessageProperties.CONTENT_TYPE_TEXT_PLAIN, message -> {
            try {
                return new String(message.getBody(), DEFAULT_CHARSET);
            } catch (UnsupportedEncodingException e) {
                throw new MessageConversionException("Failed to convert Message content", e);
            }
        });
        MSG_CONVERT_MAP.put(MessageProperties.CONTENT_TYPE_JSON, message -> {
            try {
                return JSONUtil.parseObj(new String(message.getBody(), DEFAULT_CHARSET));
            } catch (UnsupportedEncodingException e) {
                throw new MessageConversionException("Failed to convert Message content", e);
            }
        });
    }

    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        MessageProperties messageProperties = message.getMessageProperties();
        return MSG_CONVERT_MAP.get(messageProperties.getContentType()).apply(message);
    }

    @Override
    protected Message createMessage(Object objectToConvert, MessageProperties messageProperties) throws MessageConversionException {
        byte[] bytes;
        if (objectToConvert instanceof byte[]) {
            messageProperties.setContentType(MessageProperties.CONTENT_TYPE_BYTES);
            bytes = (byte[]) objectToConvert;
            } else if (objectToConvert instanceof CharSequence) {
            messageProperties.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
            messageProperties.setContentEncoding("UTF-8");
            bytes = objectToConvert.toString().getBytes(StandardCharsets.UTF_8);
        } else {
            messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
            String jsonString = JSONUtil.toJsonStr(objectToConvert);
            bytes = jsonString.getBytes(StandardCharsets.UTF_8);
        }
        messageProperties.setContentLength(bytes.length);
        return new Message(bytes, messageProperties);
    }
}
